
package com.hlkj.pay.gateway.order.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.LocalContext;
import com.hlkj.framework.common.pojo.LocalRequest;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.executor.ExtensionExecutor;
import com.hlkj.framework.extension.scenario.BizScenario;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantAccessExtPt;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantOrderExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.dto.LocalMerchantRequest;
import com.hlkj.pay.dto.order.PayOrderChannelResultDto;
import com.hlkj.pay.dto.order.SchemeOrderDto;
import com.hlkj.pay.dto.order.notify.CsOrderNotifyDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.gateway.order.IChannelPayOrderGateway;
import com.hlkj.pay.infrastructure.model.common.CommonAppDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelRequestDO;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.service.common.ICommonAppConfigService;
import com.hlkj.pay.service.common.IWechatAppService;
import com.hlkj.pay.service.merchant.IMerchantApplicationService;
import com.hlkj.pay.service.pay.IPayChannelService;
import com.hlkj.pay.service.pay.IPayWayService;
import com.hlkj.pay.service.pay.IProviderService;
import com.hlkj.pay.vo.order.req.OrderPromotionInfo;
import com.hlkj.pay.vo.order.req.PayOrderCommonParamReq;
import jodd.util.StringPool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @author HlpayTeam
 * @date 2024/11/06 13:29
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChannelPayOrderGatewayImpl implements IChannelPayOrderGateway {

    @Value("${hlkj.pay.barrier:false}")
    private boolean barrier;

    @Value("${hlkj.pay.test:false}")
    private boolean test;

    @Value("${hlkj.domain}")
    private String domain;

    private final ExtensionExecutor extensionExecutor;

    private final IMerchantApplicationService merchantApplicationService;

    private final IPayWayService payWayService;

    private final IProviderService providerService;

    private final IPayChannelService payChannelService;

    private final ICommonAppConfigService commonAppConfigService;

    private final IWechatAppService wechatAppService;

    @Override
    public CommonResult<String> channelOrderCode(PayOrderDO payOrderDO) {
        if (barrier) {
            log.info("测试环境渠道不生成特殊订单号返回成功 payOrderNo:{}", payOrderDO.getPayOrderNo());
            return CommonResult.success();
        }
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(payOrderDO.getMchChannelCode());
        ChannelPayOrderContext merchantPayOrderContext = new ChannelPayOrderContext();
        merchantPayOrderContext.setMerchantAppChannelDO(merchantAppChannelDO);
        merchantPayOrderContext.setPayOrderDO(payOrderDO);
        merchantPayOrderContext.setPayWayDO(payWayService.queryByCode(payOrderDO.getPayWayCode()));
        merchantPayOrderContext
                .setNotifyUrl(domain + MerchantExtConstant.MERCHANT_TRANS_ASYNC_CALLBACK_URL + payOrderDO.getChannelCode() + StringPool.SLASH + payOrderDO.getProviderCode());
        merchantPayOrderContext.setTest(test);
        return extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.channelOrderCode(merchantPayOrderContext));

    }

    @Override
    public PayOrderChannelResultDto submitChannelPayOrder(PayOrderDO payOrderDO) {
        if (barrier) {
            log.info("测试环境提交订单直接返回成功 payOrderNo:{}", payOrderDO.getPayOrderNo());
            PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
            payOrderChannelResultDto.setPayInfo("https://qr.alipay.com/bax04541w25lmciec7tw0073");
            payOrderChannelResultDto.setPayDataType("pay_url");
            payOrderChannelResultDto.setChannelOrderNo(payOrderDO.getPayOrderNo());
            payOrderChannelResultDto.setChannelOrderId(payOrderDO.getPayOrderNo());
            return payOrderChannelResultDto;
        }
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(payOrderDO.getMchChannelCode());
        ChannelPayOrderContext merchantPayOrderContext = new ChannelPayOrderContext();
        merchantPayOrderContext.setMerchantAppChannelDO(merchantAppChannelDO);
        merchantPayOrderContext.setPayOrderDO(payOrderDO);
        merchantPayOrderContext.setProviderChannelConfigDO(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        merchantPayOrderContext.setPayWayDO(payWayService.queryByCode(payOrderDO.getPayWayCode()));
        PayOrderCommonParamReq.Extra extra = JsonUtils.parseObject(payOrderDO.getExtra(), PayOrderCommonParamReq.Extra.class);
        if (extra == null) {
            extra = new PayOrderCommonParamReq.Extra();
            payOrderDO.setExtra(JsonUtils.toJsonStringNotNull(extra));
        }
        CommonAppDO commonAppDO = null;
        // 提交的appid不存在 取默认的
        if (!StringUtils.hasText(extra.getSubAppid())) {
            commonAppDO = queryChannelPayAppid(payOrderDO);
            if (commonAppDO != null) {
                extra.setSubAppid(commonAppDO.getAppId());
            }
        }

        if(StrUtil.isNotEmpty(payOrderDO.getAuthCode())){
            extra.setAuthCode(payOrderDO.getAuthCode());
        }

        merchantPayOrderContext
                .setNotifyUrl(domain + MerchantExtConstant.MERCHANT_TRANS_ASYNC_CALLBACK_URL + payOrderDO.getChannelCode() + StringPool.SLASH + payOrderDO.getProviderCode());
        merchantPayOrderContext.setTest(test);
        merchantPayOrderContext.setExtra(extra);

        // 转换营销信息
        OrderPromotionInfo orderPromotionInfo =  JSONUtil.toBean(payOrderDO.getMarketingOrdersJson(), OrderPromotionInfo.class);
        if(orderPromotionInfo != null){
            merchantPayOrderContext.setPromotionInfo(orderPromotionInfo);
        }

        // 获取是否需要微信中间链接  区分原生非原生
        // boolean link = extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
        //         ex -> ex.wechatLink(merchantPayOrderContext));
        PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
        payOrderChannelResultDto.setExtra(extra);
        PayWayDO payWayDO = merchantPayOrderContext.getPayWayDO();
        PayEnums.PAY_TYPE payType = PayEnums.PAY_TYPE.fromByCode(payWayDO.getType());
        PayEnums.SCENE_PAY_TYPE scenePayType = PayEnums.SCENE_PAY_TYPE.fromByType(payWayDO.getSubType());

        // AuthCode 不为空 则是 预下单
        if(extra != null && StrUtil.isNotEmpty(extra.getAuthCode())){
            // 预下单拿AuthCode去获取WxUserId
            if (payType.getCode().equals(PayEnums.PAY_TYPE.WECHAT.getCode())) {
                log.info("支付订单进入通用 微信小程序openid获取程序 channelCode:{}, appId:{},scenePayType:{}", payOrderDO.getChannelCode(), extra.getSubAppid(), scenePayType.getDesc());
                if (commonAppDO == null) {
                    commonAppDO = commonAppConfigService.detail(extra.getSubAppid(),
                            scenePayType == PayEnums.SCENE_PAY_TYPE.JSAPI ? CommonEnum.COMMON_APP_TYPE.WECHAT_PUB : CommonEnum.COMMON_APP_TYPE.WECHAT_MIN);
                }
                log.info("支付订单进入通用 微信小程序openid获取程序 commonAppDO:{}", JSONUtil.toJsonStr(commonAppDO));
                if (commonAppDO != null) {
                    CommonResult<WxMaJscode2SessionResult> resultCommonResult = wechatAppService.wxAppUserInfo(commonAppDO, extra.getAuthCode());
                    if (!resultCommonResult.isSuccess()) {
                        payOrderChannelResultDto.setProcessStatus(Boolean.FALSE);
                        payOrderChannelResultDto.setRemark("微信支付 获取用户 openid 失败:" + resultCommonResult.getMsg());
                        return payOrderChannelResultDto;
                    }
                    else {
                        WxMaJscode2SessionResult wxMaJscode2SessionResult = resultCommonResult.getData();
                        extra.setUserId(wxMaJscode2SessionResult.getOpenid());
                        log.info("微信支付 获取用户openid 成功 payOrderNo:{},openid:{},", payOrderDO.getPayOrderNo(), extra.getUserId());
                    }
                }
            }
        }else{
            // 统一下单 微信支付 H5/APP 非原生 才会跳链接
            if(extra.getOriginalType() != null &&  extra.getOriginalType() == CommonEnum.YES_NO_TYPE.NO.getCode() && !payOrderDO.isPre()){
                switch (payType){
                    case WECHAT:
                        switch (scenePayType){
                            case H5:
                            case APP:
                                log.info("支付订单进入通用 微信小程序链接获取程序 channelCode:{}, appId:{},scenePayType:{}", payOrderDO.getChannelCode(), extra.getSubAppid(), scenePayType.getDesc());
                                if (!StringUtils.hasText(extra.getSubAppid())) {
                                    payOrderChannelResultDto.setProcessStatus(Boolean.FALSE);
                                    payOrderChannelResultDto.setRemark("微信支付 appid未提交或者未配置");
                                    return payOrderChannelResultDto;
                                }
                                if (commonAppDO == null) {
                                    commonAppDO = commonAppConfigService.detail(extra.getSubAppid(),
                                            scenePayType == PayEnums.SCENE_PAY_TYPE.JSAPI ? CommonEnum.COMMON_APP_TYPE.WECHAT_PUB : CommonEnum.COMMON_APP_TYPE.WECHAT_MIN);
                                }
                                if (commonAppDO == null) {
                                    payOrderChannelResultDto.setProcessStatus(Boolean.FALSE);
                                    payOrderChannelResultDto.setRemark("微信支付 appid未配置");
                                    return payOrderChannelResultDto;
                                }
                                CommonResult<SchemeOrderDto> linkResult = wechatAppService.urlLink(commonAppDO, payOrderDO, merchantPayOrderContext.getPage());
                                if (!linkResult.isSuccess()) {
                                    payOrderChannelResultDto.setProcessStatus(Boolean.FALSE);
                                    payOrderChannelResultDto.setRemark("提交小程序 非原生支付获取小程序链接失败:" + linkResult.getMsg());
                                    return payOrderChannelResultDto;
                                }
                                else {
                                    LocalRequest localRequest = LocalContext.get();
                                    boolean oldVersion = true;
                                    if (localRequest instanceof LocalMerchantRequest) {
                                        LocalMerchantRequest localMerchantRequest = (LocalMerchantRequest) localRequest;
                                        String version = localMerchantRequest.getVersion();
                                        if (StringUtils.hasText(version)) {
                                            BigDecimal versionValue = new BigDecimal(version);
                                            //版本号大于1.01 修改断连格式
                                            if (versionValue.compareTo(new BigDecimal("1.01")) >= 0) {
                                                oldVersion = false;
                                            }
                                        }
                                    }
                                    if (oldVersion) {
                                        payOrderChannelResultDto.setPayDataType("url");
                                        payOrderChannelResultDto.setPayInfo(linkResult.getData().getSchemeCode());
                                        payOrderChannelResultDto.setRequestThird(false);
                                        return payOrderChannelResultDto;
                                    }
                                    else {
                                        payOrderChannelResultDto.setPayDataType("data");
                                        payOrderChannelResultDto.setPayInfo(JsonUtils.toJsonStringNotNull(linkResult.getData()));
                                        payOrderChannelResultDto.setRequestThird(false);
                                        return payOrderChannelResultDto;
                                    }
                                }
                        }
                        break;

                }
            }

        }

        //配置成功跳转， 未传时使用系统默认
        if (!StringUtils.hasText(payOrderDO.getRedirectUrl())) {
            merchantPayOrderContext.setRedirectUrl(domain + MerchantExtConstant.MERCHANT_TRANS_FORWARD_CALLBACK_URL + StringPool.SLASH + payOrderDO.getPayOrderNo());
        } else
            merchantPayOrderContext.setRedirectUrl(payOrderDO.getRedirectUrl());

        extensionExecutor.executeVoid(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.submitChannelPayOrder(merchantPayOrderContext));
        if(!merchantPayOrderContext.isProcessStatus()){
            payOrderChannelResultDto.setRequestChannel(true);
        }else{
            if (merchantPayOrderContext.isRequestThird() && merchantPayOrderContext.isProcessStatus()) {
                PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
                payChannelRequestDO.setRelationId(payOrderDO.getPayOrderNo());
                payChannelRequestDO.setSn(payOrderDO.getSn());
                payChannelRequestDO.setProviderCode(payOrderDO.getProviderCode());
                payChannelRequestDO.setChannelCode(payOrderDO.getChannelCode());
                payChannelRequestDO.setMchChannelCode(payOrderDO.getMchChannelCode());
                Map<String, String> params = new HashMap<>();
                params.put("payDataType", merchantPayOrderContext.getPayDataType());
                params.put("payInfo", merchantPayOrderContext.getPayInfo());
                payChannelRequestDO.setResponse(JsonUtils.toJsonString(params));
                payChannelService.saveRequest(payChannelRequestDO, PayEnums.CHANNEL_REQUEST_TYPE.PAY_ORDER);
            }
        }
        payOrderChannelResultDto.setProcessStatus(merchantPayOrderContext.isProcessStatus());
        payOrderChannelResultDto.setRemark(merchantPayOrderContext.getRemark());
        payOrderChannelResultDto.setPayInfo(merchantPayOrderContext.getPayInfo());
        payOrderChannelResultDto.setPayDataType(merchantPayOrderContext.getPayDataType());
        payOrderChannelResultDto.setInsOrderNo(merchantPayOrderContext.getInsOrderNo());
        payOrderChannelResultDto.setChannelOrderNo(merchantPayOrderContext.getChannelOrderNo());
        payOrderChannelResultDto.setChannelOrderId(merchantPayOrderContext.getChannelOrderId());
        payOrderChannelResultDto.setRequestThird(merchantPayOrderContext.isRequestThird());
        payOrderChannelResultDto.setAutCode(merchantPayOrderContext.getAutCode());
        payOrderChannelResultDto.setAutSubMerId(merchantPayOrderContext.getAutSubMerId());
        payOrderChannelResultDto.setExtra(extra);
        return payOrderChannelResultDto;
    }

    @Override
    public PayOrderChannelResultDto queryChannelPayOrder(PayOrderDO payOrderDO) {
        if (barrier) {
            log.info("测试环境查询订单支付状态 直接返回成功 payOrderNo:{}", payOrderDO.getPayOrderNo());
            PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
            PayOrderDO updartePayOrderDO = new PayOrderDO();
            updartePayOrderDO.setInsOrderNo(payOrderDO.getPayOrderNo());
            updartePayOrderDO.setAtuSubMerId(payOrderDO.getPayOrderNo());
            updartePayOrderDO.setSettlementAmount(payOrderDO.getAmount());
            updartePayOrderDO.setSuccessTime(System.currentTimeMillis());
            updartePayOrderDO.setPayAmount(payOrderDO.getAmount());
            updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode());
            payOrderChannelResultDto.setUpdatePayOrderDO(updartePayOrderDO);
            return payOrderChannelResultDto;
        }
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(payOrderDO.getMchChannelCode());
        ChannelPayOrderQueryContext channelPayOrderQueryContext = new ChannelPayOrderQueryContext();
        channelPayOrderQueryContext.setMerchantAppChannelDO(merchantAppChannelDO);
        channelPayOrderQueryContext.setPayOrderDO(payOrderDO);
        channelPayOrderQueryContext.setPayWayDO(payWayService.queryByCode(payOrderDO.getPayWayCode()));
        channelPayOrderQueryContext.setProviderChannelConfigDO(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        channelPayOrderQueryContext.setTest(test);
        extensionExecutor.executeVoid(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.queryChannelPayOrder(channelPayOrderQueryContext));
        PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
        payOrderChannelResultDto.setUpdatePayOrderDO(channelPayOrderQueryContext.getUpdartePayOrderDO());
        payOrderChannelResultDto.setPayInfo(channelPayOrderQueryContext.getPayInfo());
        payOrderChannelResultDto.setPayDataType(channelPayOrderQueryContext.getPayDataType());
        return payOrderChannelResultDto;
    }

    @Override
    public PayOrderChannelResultDto queryChannelCloseOrder(PayOrderDO payOrderDO) {
        if (barrier) {
            log.info("测试环境查询订单关闭状态 直接返回成功 payOrderNo:{}", payOrderDO.getPayOrderNo());
            PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
            PayOrderDO updartePayOrderDO = new PayOrderDO();
            updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
            payOrderChannelResultDto.setUpdatePayOrderDO(updartePayOrderDO);
            return payOrderChannelResultDto;
        }
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(payOrderDO.getMchChannelCode());
        ChannelPayOrderQueryContext channelPayOrderQueryContext = new ChannelPayOrderQueryContext();
        channelPayOrderQueryContext.setMerchantAppChannelDO(merchantAppChannelDO);
        channelPayOrderQueryContext.setPayOrderDO(payOrderDO);
        channelPayOrderQueryContext.setPayWayDO(payWayService.queryByCode(payOrderDO.getPayWayCode()));
        channelPayOrderQueryContext.setProviderChannelConfigDO(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        channelPayOrderQueryContext.setTest(test);
        extensionExecutor.executeVoid(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.queryChannelClosePayOrder(channelPayOrderQueryContext));
        PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
        payOrderChannelResultDto.setUpdatePayOrderDO(channelPayOrderQueryContext.getUpdartePayOrderDO());
        return payOrderChannelResultDto;
    }

    @Override
    public PayOrderChannelResultDto closeChannelPayOrder(PayOrderDO payOrderDO) {
        if (barrier) {
            log.info("测试环境提交关闭订单直接返回成功 payOrderNo:{}", payOrderDO.getPayOrderNo());
            PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
            return payOrderChannelResultDto;
        }
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(payOrderDO.getMchChannelCode());
        ChannelPayOrderQueryContext channelPayOrderQueryContext = new ChannelPayOrderQueryContext();
        channelPayOrderQueryContext.setMerchantAppChannelDO(merchantAppChannelDO);
        channelPayOrderQueryContext.setPayOrderDO(payOrderDO);
        channelPayOrderQueryContext.setPayWayDO(payWayService.queryByCode(payOrderDO.getPayWayCode()));
        channelPayOrderQueryContext.setProviderChannelConfigDO(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        channelPayOrderQueryContext
                .setNotifyUrl(domain + MerchantExtConstant.MERCHANT_TRANS_CLOSE_ASYNC_CALLBACK_URL + payOrderDO.getChannelCode() + StringPool.SLASH + payOrderDO.getProviderCode());
        channelPayOrderQueryContext.setTest(test);
        PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
        if(extensionExecutor.executeExist(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()))){
            extensionExecutor.executeVoid(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                    ex -> ex.closeChannelPayOrder(channelPayOrderQueryContext));

            payOrderChannelResultDto.setUpdatePayOrderDO(channelPayOrderQueryContext.getUpdartePayOrderDO());
            payOrderChannelResultDto.setProcessStatus(channelPayOrderQueryContext.isProcessStatus());
            payOrderChannelResultDto.setRemark(channelPayOrderQueryContext.getRemark());
        }
        return payOrderChannelResultDto;
    }

    @Override
    public String channelPayCode(String channelCode, PayWayDO payWayDO) {
        return extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.channelPayCode(payWayDO));
    }

    @Override
    public String callBackResponse(String channelCode, CommonResult commonResult) {
        return extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
    }

    @Override
    public CommonResult<PayOrderChannelResultDto> orderStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(providerChannelConfigDO.getChannelCode()),
                ex -> ex.orderStatusParse(request, providerChannelConfigDO));
    }

    @Override
    public CommonResult<PayOrderChannelResultDto> orderStatusParse(String channelCode, HttpServletRequest request) {
        return extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.orderStatusParse(request));
    }

    @Override
    public CommonResult<PayOrderChannelResultDto> merAuthParse(HttpServletRequest request,String channelCode) {
        return extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.merAuthParse(request));
    }

    @Override
    public PayOrderDO closeOrderStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(providerChannelConfigDO.getChannelCode()),
                ex -> ex.closeOrderStatusParse(request, providerChannelConfigDO));
    }

    @Override
    public CommonResult<CsOrderNotifyDto> csOrderStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(providerChannelConfigDO.getChannelCode()),
                ex -> ex.csOrderStatusParse(request, providerChannelConfigDO));
    }

    @Override
    public PayOrderChannelResultDto payInfoParse(PayChannelRequestDO payChannelRequestDO) {
        if (payChannelRequestDO == null) {
            return null;
        }
        String response = payChannelRequestDO.getResponse();
        Map<String, String> params = JsonUtils.parseObject(response, Map.class);
        PayOrderChannelResultDto payOrderChannelResultDto = new PayOrderChannelResultDto();
        payOrderChannelResultDto.setPayDataType(params.get("payDataType"));
        payOrderChannelResultDto.setPayInfo(params.get("payInfo"));
        return payOrderChannelResultDto;
    }

    @Override
    public boolean extensionExist(String channelCode) {
        return extensionExecutor.executeExist(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(channelCode));
    }

    @Override
    public CommonAppDO queryChannelPayAppid(PayOrderDO payOrderDO) {
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(payOrderDO.getMchChannelCode());
        ChannelPayOrderContext merchantPayOrderContext = new ChannelPayOrderContext();
        merchantPayOrderContext.setMerchantAppChannelDO(merchantAppChannelDO);
        merchantPayOrderContext.setPayOrderDO(payOrderDO);
        merchantPayOrderContext.setProviderChannelConfigDO(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        merchantPayOrderContext.setPayWayDO(payWayService.queryByCode(payOrderDO.getPayWayCode()));
        merchantPayOrderContext.setTest(test);
        Long id = extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.queryChannelPayAppid(merchantPayOrderContext));
        if (id == null) {
            return null;
        }
        CommonAppDO commonAppDO = commonAppConfigService.detail(id);
        if (commonAppDO == null)
            return null;
        return commonAppDO;
    }

}
